package com.citic.topview.system.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.citic.topview.common.bean.Query;
import com.citic.topview.common.bean.Tree;
import com.citic.topview.common.system.entity.Office;
import com.citic.topview.common.system.entity.User;
import com.citic.topview.common.system.vo.OfficeVO;
import com.citic.topview.common.util.BuildTree;
import com.citic.topview.system.dao.OfficeDao;
import com.citic.topview.system.persistence.CrudService;

@Service
@Transactional(readOnly = true)
public class OfficeService extends CrudService<OfficeDao, Office>{

	public static final String TYPE_01 = "0";
	public static final String TYPE_02 = "1";
	public static final String TYPE_03 = "2";
	
	public Office get(Long id) {
		return super.get(id);
	}

	@Transactional(readOnly = false)
	public int save(Office office) {
		return super.save(office);
	}

	@Transactional(readOnly = false)
	public int update(Office office) {
		return super.update(office);
	}

	@Transactional(readOnly = false)
	public int remove(Long id) {
		return super.remove(id);
	}

	@Transactional(readOnly = false)
	public int deleteByDelFlag(Long id) {
		return super.deleteByDelFlag(id);
	}

	@Transactional(readOnly = false)
	public int batchRemove(Long[] ids) {
		return super.batchRemove(ids);
	}

	public List<Office> findList(Map<String, Object> params) {
		return dao.findList(params);
	}
	
	public List<OfficeVO> list(Map<String, Object> params) {
		return dao.list(params);
	}
	
	public List<OfficeVO> listQuery(Map<String, Object> params) {
		return dao.listQuery(params);
	}
	
	public int count(Query query) {
		return dao.count(query);
	}

	public String listByIN(String[] ids) {
		Long[] ls = new Long[ids.length];
		for (int i = 0; i < ids.length; i++) {
			ls[i] = Long.valueOf(ids[i]);
		}
		
		List<OfficeVO> list = dao.listByIN(ls);
		StringBuffer buffer = new StringBuffer(StringUtils.EMPTY);
		for (OfficeVO officeVO : list) {
			buffer.append(officeVO.getName()).append(",");
		}
		
		return buffer.toString();
	}
	
	public Tree<OfficeVO> getCompanyTree() {
		List<Tree<OfficeVO>> trees = new ArrayList<Tree<OfficeVO>>();
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("type", TYPE_01);
		List<OfficeVO> list = dao.list(params);
		
		for (OfficeVO officeVO : list) {
			Tree<OfficeVO> tree = new Tree<OfficeVO>();
			tree.setId(officeVO.getId());
			tree.setParentId(officeVO.getParentId());
			tree.setText(officeVO.getName());
			Map<String, Object> state = new HashMap<>(16);
			state.put("opened", true);
			tree.setState(state);
			trees.add(tree);
		}
		
		// 默认顶级菜单为０，根据数据库实际情况调整
		Tree<OfficeVO> t = BuildTree.buildOffice(trees);
		return t;
	}

	public Tree<OfficeVO> getOfficeTree() {
		List<Tree<OfficeVO>> trees = new ArrayList<Tree<OfficeVO>>();
		List<OfficeVO> list = dao.list(new HashMap<String, Object>());
		
		for (OfficeVO officeVO : list) {
			Tree<OfficeVO> tree = new Tree<OfficeVO>();
			tree.setId(officeVO.getId());
			tree.setParentId(officeVO.getParentId());
			if(officeVO.getType().equals("0")) {
				tree.setIcon("user-office");
			}
			tree.setText(officeVO.getName());
			Map<String, Object> state = new HashMap<>(16);
			state.put("opened", true);
			tree.setState(state);
			trees.add(tree);
		}
		
		// 默认顶级菜单为０，根据数据库实际情况调整
		Tree<OfficeVO> t = BuildTree.buildOffice(trees);
		return t;
	}

	@Transactional(readOnly = false)
	public int removes(Long id) {
		Long parentId = get(id).getParentId();
		
		Map<String, Object> params = new HashMap<>();
		params.put("parentId", id);
		List<Office> list = findList(params);
		
		if(!CollectionUtils.isEmpty(list)) {
			params.put("offices", list);
			params.put("parentId", parentId);
			// 批量更新子机构的父ID，然后删除当前的机构
			dao.batchUpdate(params);
		}
		
		return remove(id);
	}

	public Set<String> getOfficeIdsByUser(User user) {
		Set<String> set = new HashSet<>();
		
		if(null != user) {
			String id = user.getOfficeId() + "";
			set.add(id);
			
			List<OfficeVO> list = list(new HashMap<>());
			List<String> ids = new ArrayList<>();
			for (OfficeVO officeVO : list) {
				ids.add(officeVO.getId() + "," + officeVO.getParentId());
			}
			
			processData(set, ids, id);
		}
		
		return set;
	}
	
	private void processData(Set<String> set, List<String> ids, String id) {
		boolean isTrue = false;
		for (String string : ids) {
			if(string.indexOf(id) == 0) {
				id = string.replace(id + ",", "");
				set.add(id);
				isTrue = true;
			}
		}
		
		if(isTrue) {
			processData(set, ids, id);
		}
	}
}
